package util

import (
	"context"
	"github.com/qiniu/go-sdk/v7/storage"
	"github.com/qiniu/go-sdk/v7/storagev2/credentials"
	"github.com/qiniu/go-sdk/v7/storagev2/downloader"
	"github.com/qiniu/go-sdk/v7/storagev2/http_client"
	"github.com/qiniu/go-sdk/v7/storagev2/uploader"
	"github.com/qiniu/go-sdk/v7/storagev2/uptoken"
	"github.com/spf13/viper"
	"io"
	"time"
)

type QiniuConfig struct {
	AccessKey string                   `json:"accessKey,omitempty"`
	SecretKey string                   `json:"secretKey" json:"secretKey,omitempty"`
	Bucket    string                   `json:"bucket" json:"bucket,omitempty"`
	Mac       *credentials.Credentials `json:"mac" json:"mac,omitempty"`
	Domain    string                   `json:"domain" json:"domain,omitempty"`
}

var qiniuConfig *QiniuConfig

func getConfig() *QiniuConfig {
	if qiniuConfig != nil {
		return qiniuConfig
	}
	accessKey := viper.GetString("qncloud.accessKey")
	secretKey := viper.GetString("qncloud.secretKey")
	mac := credentials.NewCredentials(accessKey, secretKey)
	bucket := viper.GetString("qncloud.bucket")
	qiniuConfig = &QiniuConfig{
		AccessKey: accessKey,
		SecretKey: secretKey,
		Bucket:    bucket,
		Mac:       mac,
		Domain:    viper.GetString("qncloud.domain"),
	}
	return qiniuConfig
}

func GetUploadToken() (string, error) {
	mac := getConfig().Mac
	bucket := getConfig().Bucket
	putPolicy, err := uptoken.NewPutPolicy(bucket, time.Now().Add(1*time.Hour))
	if err != nil {
		return "", err
	}
	result, err := uptoken.NewSigner(putPolicy, mac).GetUpToken(context.Background())
	if err != nil {
		return "", err
	}
	return result, nil
}

func UploadStream(reader io.Reader, key string, fileName string) error {
	mac := getConfig().Mac
	bucket := getConfig().Bucket
	uploadManager := uploader.NewUploadManager(&uploader.UploadManagerOptions{
		Options: http_client.Options{
			Credentials: mac,
		},
	})
	err := uploadManager.UploadReader(context.Background(), reader, &uploader.ObjectOptions{
		BucketName: bucket,
		ObjectName: &key,
		CustomVars: map[string]string{
			"": "",
		}, //定义元数据信息
		FileName: fileName,
	}, nil)
	if err != nil {
		return err
	}
	return nil
}

func GetUrlsProvider() downloader.DownloadURLsProvider {
	mac := getConfig().Mac
	domain := getConfig().Domain
	urlsProvider := downloader.
		SignURLsProvider(downloader.NewStaticDomainBasedURLsProvider([]string{domain}),
			downloader.NewCredentialsSigner(mac), &downloader.SignOptions{
				TTL: 24 * time.Hour, // 有效期
			})
	return urlsProvider
}

func GetFileUrl(key string) string {
	mac := getConfig().Mac
	domain := getConfig().Domain
	expireSeconds := 3600 * 24
	deadline := time.Now().Add(time.Duration(expireSeconds) * time.Second).Unix()
	url := storage.MakePrivateURLv2(mac, domain, key, deadline)
	return url
}
